#include "include.h"
#include "SPIPacket.h"

char spi_frame_RX[BYTE_LEN] = {0};

/*
 执行硬件上的SPI数据传输 
 fd:SPI设备文件句柄
 tx:发送缓冲器指针
 rx:接收缓冲区指针
 len:收发的数据个数
*/
static int transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
	int ret = 0;
	struct spi_ioc_transfer tr;
	/* 设置SPI传输的控制结构体 */
	memset(&tr, 0, sizeof(struct spi_ioc_transfer));
	tr.tx_buf = (unsigned long)tx;	// 发送缓冲区
	tr.rx_buf = (unsigned long)rx;	// 接收缓冲区
	tr.len = len;					// 收发数据个数
	tr.delay_usecs = 0;				// SPI周期间的延时
	tr.speed_hz = speed;			// SPI时钟频率
	tr.bits_per_word = bits;		// SPI周期中的字节的bit数
	/* 执行SPI传输 */
	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	usleep(3000);
	if (ret < 1)
	{
		printf("\ncan't send spi message\r\n");
		return (ret = 1);
	}
	return (ret = 0);
}

static OTASPIMsg_t spi_frame_TX = {
	.size = BYTE_LEN,
	.bufftype = SPI_BUFFER_OTA,
	.hBus = 0x0,
	.time = {0x00000000,0x00000000},
/**
 * @tag[0]: It used to store the TotalPacket
 * @tag[1]: It used to store the CurrentBasePacket.
*/
	.tag = {0x00000000,0x00000000},
// @res1: available data size
	.res1 = 0,
	.crc8 = 0,
// @
	.msgtype = (SPI_MSGTYPE_NORM | SPI_MSGTYPE_BGN),
	.id = 0x00000000,
//@data8    
	.data8 = {0}
};

BinFileInfo binfile_info;
//todo: argv[1] is the binfile name,argv[2] is slot A/B.
int main(int argc, char *argv[])
{
	int ret = 0;
	FrameInfo_t FrameInfo;
	int MCUSPI_fd = 0;
	unsigned char rx[BYTE_LEN] = {0};
	unsigned char tx[BYTE_LEN] = {0};
	unsigned char spi_data_ok = 0;
	OTA_SinglePacketInfo_t Spacket_info;

    //1.check whether the input's parameter illegal or not.
    if (argc!= 3)
    {
        fprintf(stderr, "Usage: %s [BinFileName] [A/B]\r\n", argv[0]);
        exit(EXIT_FAILURE); //exit with error code. EXIT_FAILURE means the program terminated abnormally.
    }

	//2.parse OTAfile
	File_parse(argv[1],argv[2],&binfile_info);

	//3.Set the SPI device
	MCUSPI_fd = SPISet(device);

	//4.Config the SPI TX_frame
	//4.1 Get total packet number
	FrameInfo.TotalPacket = OTATotalPacketNum(binfile_info.fileLength);
	//4.2 Set the SPI TX_frame  //
	for(FrameInfo.CurrentPacket = 0; FrameInfo.CurrentPacket < FrameInfo.TotalPacket; FrameInfo.CurrentPacket++)
	{
		//4.2.1 Use BinFile information to Create SinglePacket information
		BinFileConvertToSP(binfile_info,FrameInfo,&Spacket_info);
		//4.2.2 Create SPI TX_frame		
		FillSingleFrame(&Spacket_info,&spi_frame_TX);
		//4.2.3 Send SPI TX_frame
		//发送SPI数据，并获得接收到的SPI数据
		memcpy(tx, (char *)&spi_frame_TX, BYTE_LEN);
		ret = transfer(MCUSPI_fd, tx, rx, BYTE_LEN);
		
		//4.2.4 Receive SPI RX_frame
		// memcpy((char *)&spi_frame_RX, rx, BYTE_LEN);
		// for(unsigned int i=0; i<92; i++)
		// {
		// 	printf("%02x ", rx[i]);
		// }
	}
	File_close(&binfile_info);
	close(MCUSPI_fd);
	fprintf(stdout, "Update MCU firmware [%s] successfully! New Fireware is valid when waiting for reboot...\r\n", argv[1]);
	return ret;
}
